package forms;


import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.TimeUnit;


import javax.servlet.http.HttpServletRequest;


import model.VenueModel;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.util.LabelValueBean;

import db.DBModel;
import exceptions.ClockException;

public class EventFormInsertUpdate extends ActionForm{

	private static final long serialVersionUID = 1L;
	/**
	 * First we provide initial values for all of the input fields that have names matching the property names of the bean, with appropriate getters and setters.
	 */
	
	private String eventId = null;
	private String eventName=null;
	private String date=null;
	private String time=null;
	private String desc=null;
	private String minCapacity=null;
	private String maxCapacity=null;
	private String venue=null;
	private String venueName=null;
	private String venueAddress=null;
	private String venueDescription=null;
	private String venueCapacity=null;
	private Collection venueList=null;
	
	public String getEventId() {
		return eventId;
	}

	public void setEventId(String eventId) {
		this.eventId = eventId;
	}
	
	public Collection getVenueList() {
		return venueList;
	}

	public void setVenueList(Collection venueList) {
		this.venueList = venueList;
	}

	public String getEventName() {
		return eventName;
	}

	public void setEventName(String eventName) {
		this.eventName = eventName;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public String getMinCapacity() {
		return minCapacity;
	}

	public void setMinCapacity(String minCapacity) {
		this.minCapacity = minCapacity;
	}

	public String getMaxCapacity() {
		return maxCapacity;
	}

	public void setMaxCapacity(String maxCapacity) {
		this.maxCapacity = maxCapacity;
	}

	public String getVenue() {
		return venue;
	}

	public void setVenue(String venue) {
		this.venue = venue;
	}

	public String getVenueName() {
		return venueName;
	}

	public void setVenueName(String venueName) {
		this.venueName = venueName;
	}

	public String getVenueAddress() {
		return venueAddress;
	}

	public void setVenueAddress(String venueAddress) {
		this.venueAddress = venueAddress;
	}

	public String getVenueDescription() {
		return venueDescription;
	}

	public void setVenueDescription(String venueDescription) {
		this.venueDescription = venueDescription;
	}

	public String getVenueCapacity() {
		return venueCapacity;
	}

	public void setVenueCapacity(String venueCapacity) {
		this.venueCapacity = venueCapacity;
	}

	/**
	 * Reset all properties to their default values.
	 * 
	 * @param mapping
	 *            The mapping used to select this instance
	 * @param request
	 *            The servlet request we are processing
	 */
	public void reset(ActionMapping mapping, HttpServletRequest request) {
		setEventName(null);
		setDate(null);
		setTime(null);
		setDesc(null);
		setMinCapacity(null);
		setMaxCapacity(null);
		setVenue(null);
		setVenueName(null);
		setVenueAddress(null);
		setVenueDescription(null);
		setVenueCapacity(null);
	}

	/**
	 * Validate the input data. If validation fails, then report the errors in
	 * createevent.jsp, and specifically where <html:errors/> is located.
	 * 
	 * @param mapping
	 *            The mapping used to select this instance
	 * @param request
	 *            The servlet request we are processing
	 */
	@SuppressWarnings("deprecation")
	public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {

		ActionErrors errors = new ActionErrors();
			
			int minCapacity = -1;
	        int maxCapacity = -1;

	        String eventName = request.getParameter("eventName");
	        if (checkIfStringIsNotValid(eventName)) {	            
	        	errors.add("eventName", new ActionMessage("errors.required", "Event name"));
	        }
	        //
	        
	        String date = request.getParameter("date").trim(); // format: mm/dd/yyyy
	        String time = request.getParameter("time").trim();
	        
	        if (checkIfStringIsNotValid(date) || checkIfStringIsNotValid(time)) {
	        	if(checkIfStringIsNotValid(date)){
		        	errors.add("date", new ActionMessage("errors.required", "Date"));
	        	}
	        	if(checkIfStringIsNotValid(time)){
		        	errors.add("time", new ActionMessage("errors.required", "Time"));
	        	}
	        }
	        else
	        {
	        	int year, month, day, hour, minute;
	        	try{
	        		String[] dateString = date.split("/");
	        		month = Integer.parseInt(dateString[0]);
	        		day = Integer.parseInt(dateString[1]);
	        		year = Integer.parseInt(dateString[2]);
	        		String[] timeString = time.split(":");
	        		hour = Integer.parseInt(timeString[0]);
	        		minute = Integer.parseInt(timeString[1].trim());
	        		Calendar calendar = Calendar.getInstance();
	        		Calendar compareCalendar = Calendar.getInstance();
	        		calendar.add(Calendar.HOUR, 2);
	        		compareCalendar.setTime(calendar.getTime());	        		
	        		
	        		calendar.set(Calendar.MONTH, month-1);
	        		calendar.set(Calendar.DATE, day);
	        		calendar.set(Calendar.YEAR, year);
	        		calendar.set(Calendar.HOUR_OF_DAY, hour);
	        		calendar.set(Calendar.MINUTE, minute);
	        		if(calendar.before(compareCalendar)) throw new ClockException();
	        	}
	        	catch(NumberFormatException nme){
	        		errors.add("date", new ActionMessage("errors.invalid", "Date"));
	        	}
	        	catch(ClockException ce) {	        		
	        		errors.add("time", new ActionMessage("errors.timeexceededlimit", "Time"));
	        	}
	        	catch(NullPointerException npe) {
	        		errors.add("date", new ActionMessage("errors.invalid", "Date"));
	        	}

	        }
	        
	        String desc = request.getParameter("desc");
	        if (checkIfStringIsNotValid(desc)) {	        	
	        	errors.add("desc", new ActionMessage("errors.required", "Description"));
	        }
	        
	        String minCapacityString = request.getParameter("minCapacity");
	        if(checkIfStringIsNotValid(minCapacityString))
	        {	        	
	        	errors.add("minCapacity", new ActionMessage("errors.required", "Minimum capacity"));
	        }
	        else
	        {
	        	try{
		        	minCapacity = Integer.parseInt(minCapacityString.trim());
		        	if(minCapacity<=0){		        			        		
		        		errors.add("minCapacity", new ActionMessage("errors.invalid", "Minimum capacity"));
		        	}
	        	}catch(Exception e){	        		
	        		errors.add("minCapacity", new ActionMessage("errors.notanumber", "Minimum capacity"));
	        	}
	        }
	        
	        String maxCapacityString = request.getParameter("maxCapacity");
	        if(!(checkIfStringIsNotValid(maxCapacityString))){
	        	try{
		        	maxCapacity = Integer.parseInt(maxCapacityString.trim());
		        	if( (maxCapacity < minCapacity) && maxCapacity!=-1)
		        	{		        		
		        		errors.add("maxCapacity", new ActionMessage("errors.lessthanmin", "Maximum capacity"));
		        	}
	        	}catch(Exception e){	        		
	        		errors.add("maxCapacity", new ActionMessage("errors.notanumber", "Maximum capacity"));
	        	}
	        }
			
			int venue = Integer.parseInt(request.getParameter("venue"));
	        if(venue == 0) {	        
	        	setVenueList(getVenueListCollection());
	        	errors.add("venue", new ActionMessage("errors.required", "Venue"));
	        }
	        else{
				setVenueList(getVenueListCollection(venue));
	        }
		
		return errors;
	}
		
	private boolean checkIfStringIsNotValid(String input){
		if(input==null || input.trim().isEmpty()){
			return true;
		}
		return false;
	}
	
	private Collection getVenueListCollection(int venueId){
		try{
			DBModel db= new DBModel();
			ArrayList<VenueModel> venues = db.getAllVenues();
			String venueName = db.getVenueName(venueId);
			Collection venueList=new Vector(venues.size());
			//Adds the already selected venue first
			venueList.add(new LabelValueBean(venueName, String.valueOf(venueId)));
			for(int i=0;i<venues.size();i++){
				if(venues.get(i).getId()!=venueId){
					venueList.add( new LabelValueBean(venues.get(i).getName(),String.valueOf(venues.get(i).getId())) );
				}
			}
			db.commit();
			db.close();
			return venueList;
		}catch(Exception e){
			return null;
		}
	}
	
	private Collection getVenueListCollection(){
		try{
			DBModel db= new DBModel();
			ArrayList<VenueModel> venues = db.getAllVenues();
			Collection venueList=new Vector(venues.size());
			for(int i=0;i<venues.size();i++){
					venueList.add( new LabelValueBean(venues.get(i).getName(),String.valueOf(venues.get(i).getId())) );
			}
			db.commit();
			db.close();
			return venueList;
		}catch(Exception e){
			return null;
		}
	}
	
}
